package com.github.baichuan.application.scaffold.rest.domain.app;

import com.github.baichuan.application.scaffold.rest.domain.application.Application;
import com.github.baichuan.application.scaffold.rest.domain.application.ApplicationService;
import com.github.baichuan.application.scaffold.rest.dto.app.AppForm;
import com.github.baichuan.application.scaffold.rest.jpa.app.AppRepository;
import com.github.baichuan.application.scaffold.rest.jpa.app.AppVersionRepository;
import com.github.baichuan.web.dto.Result;
import com.github.baichuan.web.error.NoSuchEntityException;
import com.github.baichuan.utils.SnowFlake;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Optional;

@Service
@Transactional(rollbackFor = Exception.class)
public class AppService {
    @Autowired
    private AppRepository appRepository;
    @Autowired
    private AppVersionRepository appVersionRepository;
    @Autowired
    private ApplicationService applicationService;
    @Autowired
    private SnowFlake snowFlake;

    public App find(String id){
        return appRepository.findById(id).orElseThrow(() -> new NoSuchEntityException("APP应用不存在"));
    }

    public App find(Application application, App.Platform platform, String appCode){
        return appRepository.find(application, platform, appCode).orElseThrow(() -> new NoSuchEntityException("APP应用不存在"));
    }

    public Page<App> query(Specification<App> specification, Pageable pageable){
        return appRepository.findAll(specification, pageable);
    }

    public Result add(String applicationCode, AppForm form){
        Application application = applicationService.findByCode(applicationCode);

        if(appRepository.find(application, form.getPlatform(), form.getCode().trim()).isPresent()){
            return Result.fail("应用已存在");
        }

        App app = new App();
        app.setId(snowFlake.nextBase62Id().substring(5));
        app.setApplication(application);
        merge(form, app);
        appRepository.save(app);
        return Result.success("APP应用添加成功", app.getId());
    }

    public Result edit(String applicationCode, String id, AppForm form){
        Application application = applicationService.findByCode(applicationCode);
        App app = find(id);

        Optional<App> duplicate = appRepository.find(application, form.getPlatform(), form.getCode().trim());
        if(duplicate.isPresent() && !duplicate.get().getId().equals(id)){
            return Result.fail("应用已存在");
        }

        merge(form, app);
        appRepository.save(app);
        return Result.success("APP应用保存成功");
    }

    public Result remove(String applicationCode, String id){
        App app = find(id);

        if(app.getLatestVersion() != null) {
            return Result.fail("请先删除已发布的版本");
        }

//        appVersionRepository.deleteByApp(app);
        appRepository.delete(app);
        return Result.success("APP应用删除成功");
    }


    private static void merge(AppForm form, App app) {
        app.setName(form.getName().trim());
        app.setCode(form.getCode().trim());
        app.setPlatform(form.getPlatform());
    }
}
